﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace pigs
{
    /// <summary>
    /// this is the line class from the tutorial
    /// </summary>
    class Line
    {
        float slope; // The slope of a line
        float yIntercept; // Where the y value is at x = 0
        public Vector2 point1; // The left end of the line
        public Vector2 point2; // The right end of the line

        /// <summary>
        /// Constructor for a line between two poitns
        /// </summary>
        /// <param name="newPoint1">The first point
        /// <param name="newPoint2">The second point
        public Line(Vector2 newPoint1, Vector2 newPoint2)
        {
            // If the x of the first point is <= the x of the second point, set it as point 1 and point 2 as point 2
            // Otherwise set the second point as point1 and the first point as point2
            if (newPoint1.X <= newPoint2.X)
            {
                point1 = newPoint1;
                point2 = newPoint2;
            }
            else
            {
                point1 = newPoint2;
                point2 = newPoint1;
            }

            // Compute the slop and y-intercept of the line
            slope = (point1.Y - point2.Y) / (point1.X - point2.X);
            yIntercept = point1.Y - slope * point1.X;
        }

        // Determines if the calling line and the other line intersect
        public bool Intersects(Line otherLine)
        {
            if (slope == otherLine.slope)
            {
                // If they are the same line they intersect.
                if (yIntercept == otherLine.yIntercept)
                {
                    return true;
                }
                // They are parellel so they will never intersect.
                else
                {
                    return false;
                }
            }

            if (float.IsInfinity(slope))
            {
                float y = otherLine.slope * point1.X + otherLine.yIntercept;
                float maxY = Math.Max(point1.Y, point2.Y);
                float minY = Math.Min(point1.Y, point2.Y);
                if (y >= minY && y <= maxY)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

            if (float.IsInfinity(otherLine.slope))
            {
                float y = slope * otherLine.point1.X + yIntercept;
                float otherMaxY = Math.Max(otherLine.point1.Y, otherLine.point2.Y);
                float otherMinY = Math.Min(otherLine.point1.Y, otherLine.point2.Y);
                float maxY = Math.Max(point1.Y, point2.Y);
                float minY = Math.Min(point1.Y, point2.Y);
                if (y >= minY && y <= maxY && y >= otherMinY && y <= otherMaxY && (point1.X < otherLine.point1.X))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

            // Calculate the point where they intercept.
            float xIntersect = (yIntercept - otherLine.yIntercept) / (otherLine.slope - slope);
            float otherMaxX = Math.Max(otherLine.point1.X, otherLine.point2.X);
            float otherMinX = Math.Min(otherLine.point1.X, otherLine.point2.X);
            float maxX = Math.Max(point1.X, point2.X);
            float minX = Math.Min(point1.X, point2.X);
            // Check to see if the intercept point is within the two line segments
            if (minX <= xIntersect && xIntersect <= maxX && otherMinX <= xIntersect && xIntersect <= otherMaxX)
            {
                return true;
            }
            // If it is outside then they two lines don't collide.
            else
            {
                //if (otherLine.slope == 0)

                return false;
            }
        }

        // Determines whether the calling line intersects a given rectangle
        public bool Intersects(Rectangle rectangle)
        {
            Vector2 recPoint1, recPoint2, recPoint3, recPoint4;
            // Top left corner of the rectangle.
            recPoint1.X = rectangle.X;
            recPoint1.Y = rectangle.Y;

            // Top right corner of the rectangle
            recPoint2.X = rectangle.X + rectangle.Width;
            recPoint2.Y = rectangle.Y;

            // Bottom left corner
            recPoint3.X = rectangle.X;
            recPoint3.Y = rectangle.Y + rectangle.Height;

            // Bottom right corner
            recPoint4.X = rectangle.X + rectangle.Width;
            recPoint4.Y = rectangle.Y + rectangle.Height;

            // Define the four lines of the rectangle moving clockwise from the top left corner.
            // 1--2
            // |  |
            // 3--4
            Line recLine12 = new Line(recPoint1, recPoint2);
            Line recLine24 = new Line(recPoint2, recPoint4);
            Line recLine43 = new Line(recPoint4, recPoint3);
            Line recLine31 = new Line(recPoint3, recPoint1);
            if (this.Intersects(recLine12) || this.Intersects(recLine24) || this.Intersects(recLine43) || this.Intersects(recLine31))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Draw(SpriteBatch spriteBatch, Texture2D texture)
        {
            int distance = (int)Vector2.Distance(point1, point2);
            float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);

            spriteBatch.Draw(texture, new Rectangle((int)point1.X, (int)point1.Y, distance, 1), new Rectangle(0, 0, 1, 1), Color.White, angle, Vector2.Zero, SpriteEffects.None, 2.0f);
        }
    }
}